package tool.cfgvisitors;

import org.antlr.v4.runtime.tree.ParseTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tool.antlr4.CBaseListener;
import tool.antlr4.CParser;
import tool.model.GraphNode;
import tool.model.cfg.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;

public class CCfgVisitor extends CBaseListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(CCfgVisitor.class);
    private HashMap<String, ArrayList<EntryNode>> cfgs = new HashMap<>();
    private EntryNode entryNode;
    private ExitNode exitNode;

    //条件节点
    private LinkedList<GraphNode> conditions  = new LinkedList<>();

    //循环开始
    private LinkedList<GraphNode> cycleBeginNodes = new LinkedList<>();

    //循环结束
    private LinkedList<GraphNode> cycleEndNodes  = new LinkedList<>();
    
    //case | default
    private LinkedList<String> caseOrdefaultStatements  = new LinkedList<>();

    //if
    private LinkedList<ParseTree> ifStatements = new LinkedList<>();
    private GraphNode preIfNodes;
    //else
    private LinkedList<ParseTree> elseStatements = new LinkedList<>();
    private GraphNode preElseNodes;
        
    //函数调用
    private LinkedList<ParseTree> MethodCallNodeList = new LinkedList<>();
    
    //全局变量声明
    private LinkedList<ParseTree> GlobalDefinitionsList = new LinkedList<>();
    
    //变量名称
    private LinkedList<String> varDefinition = new LinkedList<>();
    
    private GraphNode currentNode;
    
    //无法确定父节点的头结点
    private GraphNode unPreNode = null;
    //循环内if-else中是否有break;
    private GraphNode unJumpNode = null;
    
    //if内是否有复杂语句的
    private boolean preIfType = false;
    //else内是否有复杂语句的
    private boolean preElseType = false;

    private int identifierGen = 0;
    private boolean inMethod = false;
    private String fileName;

    public CCfgVisitor(String fileName) {
        this.fileName = fileName;
    }

    private String getId() {
        String id = String.valueOf(identifierGen) + ".";
        identifierGen++;
        return id;
    }

    private void initNewCFG(String methodName) {
        String entryName = "Entry \n" + methodName;
        entryNode = new EntryNode(getId() + entryName);
        entryNode.setFilePath(fileName);
        entryNode.setMethodName(methodName);
        currentNode = entryNode;
        exitNode = new ExitNode(getId() + "Exit \n"+methodName);
    }

    private void endNewCFG() {
        if(!cfgs.containsKey(entryNode.getFilePath())) {
            cfgs.put(entryNode.getFilePath(), new ArrayList<>());
        }
        if(!GlobalDefinitionsList.isEmpty()){
        	String name = "{";
        	for (ParseTree parseTree : GlobalDefinitionsList) {
				name = name + parseTree.getText(); 
			}
        	name = name + "}";
        	//System.out.println("name="+name);
        	String entryName = "全局定义\n" + name;
        	EntryNode varDeclNode = new EntryNode(getId() + entryName + "\n" + def_use(GlobalDefinitionsList, 0));
        	varDeclNode.setFilePath(fileName);
        	varDeclNode.setMethodName(name);
        	cfgs.get(entryNode.getFilePath()).add(varDeclNode);
        }
        
        entryNode.setExitNode(exitNode);
        entryNode.addNodeToLeaves(exitNode);
        cfgs.get(entryNode.getFilePath()).add(entryNode);
    }

    public HashMap<String, ArrayList<EntryNode>> getCFGs() {
        return cfgs;
    }

    @Override
    public void enterFunctionDefinition(CParser.FunctionDefinitionContext ctx) {
        inMethod = true;
        String text = ctx.getText();
        String methodName = text.substring(0, text.indexOf("("));
        System.out.println("进入函数：" + methodName);
        MethodCallNodeList.add(ctx);
        initNewCFG(methodName);
    }

    @Override
    public void exitFunctionDefinition(CParser.FunctionDefinitionContext ctx) {
        System.out.println("函数结束");
        if(!lastSentence.isEmpty()){
	        NormalNode normalNode = new NormalNode(getId() + "其他块\n" + "{" + lastSentence + "}" + "\n" + def_use(lastSentence));
	    	currentNode.addSuccessor(normalNode);
	    	currentNode = normalNode;
	        lastSentence = "";
        }
        endNewCFG();
        inMethod = false;
        
    }

    boolean leftBracket = false, rightBracket = false,
    		ifBtn = false;
    @Override
    public void enterSelectionStatement(CParser.SelectionStatementContext ctx) {//if switch
    	System.out.println("enterSelectionStatement:"+ctx.getText());
        if(!inMethod) return;
        if(!lastSentence.isEmpty()){
	        NormalNode normalNode = new NormalNode(getId() + "其他块\n" + "{" + lastSentence + "}" + "\n" + def_use(lastSentence));
	    	currentNode.addSuccessor(normalNode);
	    	currentNode = normalNode;
	        lastSentence = "";
        }

        //进入新的复杂语句前判断外面是否有if-else
        if(preIfNodes!=null){
        	currentNode.addSuccessor(preIfNodes);
        	preIfNodes = null;
        }
        if(preElseNodes!=null){
        	currentNode.addSuccessor(preElseNodes);
        	preElseNodes = null;
        }
        System.out.println("preElseType="+preElseType);
        if(ctx.getText().startsWith("if")){
	        IfBeginNode ifBeginNode = new IfBeginNode(getId() + "If开始\n");
	        ConditionNode condNode = new ConditionNode(getId() +"判断条件");
	        condNode.setParentType("if");
	        conditions.push(condNode);
	        if(preElseType && !elseStatements.isEmpty()) unPreNode = ifBeginNode;
	        else currentNode.addNodeToLeaves(ifBeginNode);
	        ifBeginNode.addSuccessor(condNode);
	        currentNode = condNode;
        }
        if(ctx.getText().startsWith("switch")){
	        SwitchBeginNode switchBeginNode = new SwitchBeginNode(getId() + "Switch开始\n");
	        
	        ConditionNode condNode = new ConditionNode(getId() +"判断条件");
	        condNode.setParentType("switch");
	        conditions.push(condNode);
	        currentNode.addNodeToLeaves(switchBeginNode);
	        switchBeginNode.addSuccessor(condNode);
	        currentNode = condNode;
        }
        int childCount = ctx.getChildCount();
        for(int i = 0; i < childCount; i++) {
            String nodeName = ctx.getChild(i).getText();
            System.out.println("enterSelectionStatement:nodeName="+nodeName);
            
            switch(nodeName){
            	case "if":
            		ifBtn = true;
            		break;
            	case "(":
            		leftBracket = true;
            		break;
            	case ")":
            		rightBracket = true;
            		break;
            }
            
            if(ifBtn && leftBracket && rightBracket) {
            	if(childCount > (i + 1)) {
            		String ifContent = ctx.getChild(i + 1).getText();
            		System.out.println("if="+ifContent);
            		if(ifContent.contains("while")||ifContent.contains("for")||ifContent.contains("do{")){
            			preIfType = true;
            		}
                    ifStatements.add(ctx.getChild(i + 1));   
                    leftBracket = false;
                    rightBracket = false;
                	ifBtn = false;
                }
            }
            if("else".equals(nodeName) ||
                    "else if".equals(nodeName)) {
                if(childCount > (i + 1)) {
                    elseStatements.add(ctx.getChild(i + 1));
                    String elseContent = ctx.getChild(i + 1).getText();
                    if(elseContent.contains("while")||elseContent.contains("for")||elseContent.contains("if(")){
            			preElseType = true;
            		}
                }
            }
        }

    }

    @Override
    public void exitSelectionStatement(CParser.SelectionStatementContext ctx) {
    	System.out.println("exitSelectionStatement:"+ctx.getText());
        if(!inMethod) return;
        casedefaultFlag = false;
        GraphNode condNode = conditions.pop();
        if(condNode.getParentType().equals("if")){
        	IfEndNode ifEndNode = new IfEndNode(getId() + "If结束");
        	//结束前把if两个分支加入
            if(preIfNodes!=null){
            	condNode.addSuccessor(preIfNodes);
            	if(unJumpNode!=null){
            		preIfNodes.addSuccessor(unJumpNode);
            		unJumpNode = null;
            	}else
            	if(unPreNode!=null && preIfType) {
            		preIfNodes.addSuccessor(unPreNode);
            		unPreNode = null;
            	}
            	else preIfNodes.addSuccessor(ifEndNode);
            	preIfNodes = null;
            }
            if(preElseNodes!=null){
            	condNode.addSuccessor(preElseNodes);
            	if(unJumpNode!=null){
            		preIfNodes.addSuccessor(unJumpNode);
            		unJumpNode = null;
            	}else
            	if(unPreNode!=null && preElseType) {
            		preElseNodes.addSuccessor(unPreNode);
            		unPreNode = null;
            	}
            	else preElseNodes.addSuccessor(ifEndNode);
            	preElseNodes = null;
            }else{
            	
            	condNode.addSuccessor(ifEndNode);
            }
            
            if(!cycleEndNodes.isEmpty()) {
                condNode.addNodeToLeaves(ifEndNode, cycleEndNodes.getFirst());
            }
            else {
                condNode.addNodeToLeaves(ifEndNode);
            }
            //condNode.addSuccessor(ifEndNode);
            currentNode = ifEndNode;
        }
        if(condNode.getParentType().equals("switch")){
        	SwitchEndNode switchEndNode = new SwitchEndNode(getId() + "Switch结束");
        	//结束前把所有case和default分支加进来
        	System.out.println("switch结束");
        	for (int i=caseOrdefaultStatements.size()-1;i>=0;i--) {
				String caseCodes = caseOrdefaultStatements.get(i);
				CaseNode caseNode = new CaseNode(getId() + "case\n" + "{" +otherSentences(caseCodes) + "}" + "\n" + def_use(caseCodes));
				condNode.addSuccessor(caseNode);
				if(caseCodes.contains("while")||caseCodes.contains("for")){
					if(unPreNode!=null){
						caseNode.addSuccessor(unPreNode);
	            		unPreNode = null;
					}
				}else{
					caseNode.addSuccessor(switchEndNode);
				
				}
			}
        	if(!cycleEndNodes.isEmpty()) {
                condNode.addNodeToLeaves(switchEndNode, cycleEndNodes.getFirst());
            }
            else {
                condNode.addNodeToLeaves(switchEndNode);
            }
        	currentNode = switchEndNode;
        }
    }

    @Override
    public void enterExpression(CParser.ExpressionContext ctx) {
    	System.out.println("enterExpression:"+ctx.getText());
    	String line = ctx.getText();
    	//System.out.println(ctx.parent.getText());
        if(!inMethod) return;
        if(!conditions.isEmpty()) {
    		String name1 = currentNode.getName().substring(currentNode.getName().length()-4);
    		//if(name.equals("判断条件"))	
        	String name2 = currentNode.getParentType();
        	System.out.println("getParentType="+name2);
        	if(name1.contains("判断条件")){
	        	if(name2.equals("while")||name2.equals("if")||name2.equals("switch")||name2.equals("dowhile")){
	        		currentNode.setName(currentNode.getName() + "\n" + line + "\n" + use(line));
	        	}else if(name2.equals("for")){
	        		currentNode.setName(currentNode.getName().replaceAll("判断条件", "for初始条件语句") + "\n" + "{" + ctx.parent.getText() + "}" + "\n" + def_use(ctx.parent.getText()));
	        	}
        	}
    	}
        /*if(ctx.getText().matches("\\s*\\w*\\s*\\(.*")) {
            System.out.println("enterExpression:line=" + line);
            MethodCallNode methodCallNode = new MethodCallNode(getId() + "\nMethodCall");
            currentNode.addSuccessor(methodCallNode);
        }*/
        
    }
    @Override
    public void exitExpression(CParser.ExpressionContext ctx) {
    	System.out.println("exitExpression:"+ctx.getText());
    	//String line = ctx.getText();
    	
        if(!inMethod) return;
        
    }

    @Override
    public void enterDeclaration(CParser.DeclarationContext ctx) {
    	System.out.println("enterDeclaration:"+ctx.getText());
        if(!inMethod) {
        	GlobalDefinitionsList.add(ctx);	//方法外的常量
        	return;
        }
        String line = ctx.getText();
        if(line.matches("\\s*\\w*\\s*\\(.*")) {
        	MethodCallNodeList.add(ctx);
        	//函数结束前最后语句模块
            if(conditions.isEmpty() && cycleEndNodes.isEmpty() && !innerStruct(line)){
            	lastSentence = lastSentence + line;
            }
            /*MethodCallNode methodCallNode = new MethodCallNode(getId() + "函数调用\n" + line);
            currentNode.addSuccessor(methodCallNode);
            currentNode = methodCallNode;*/
        } else {
        	String str[] = ctx.getChild(1).getText().split(",");
    		for(int j=0;j<str.length;j++){
    			String name = str[j].split("=")[0];
    			if(!name.equals(";")) {
    				System.out.println("var:"+name);
    				varDefinition.add(name);
    			}
    			
    		}
            VarAssignNode varAssignNode = new VarAssignNode(getId() + "变量声明\n" + line + "\n" +def_use(ctx,0));
            currentNode.addSuccessor(varAssignNode);
            currentNode = varAssignNode;
        }
    }
    @Override
    public void exitDeclaration(CParser.DeclarationContext ctx) {
    	/*for (ParseTree parseTree : MethodCallNodeList) {
			lastSentence = lastSentence + parseTree.getText();
		}*/
    	System.out.println("exitDeclaration:"+ctx.getText());
        if(!inMethod) return;
        //String line = ctx.getText();
    	//if(line.matches("\\s*\\w*\\s*\\(.*")) MethodCallNodeList.pop();
    	
    }
    private boolean casedefaultFlag = false;
    private boolean preCaseFlag = false;
    @Override
    public void enterStatement(CParser.StatementContext ctx) {
    	System.out.println("enterStatement:"+ctx.getText());
        if(!inMethod) return;  
        String line = ctx.getText();
        if(ifStatements.contains(ctx)) {
        	//GraphNode condNode = conditions.getFirst();
        	String codes = (ctx.getText().startsWith("{")) ?(ctx.getText().substring(1, ctx.getText().length()-1)):(ctx.getText());
        	String defUseName = def_use(codes);
            System.out.println("defUseName="+defUseName);
        	IfNode ifNode = new IfNode(getId() + "if\n" + "{" + otherSentences(codes) + "}" + "\n" + defUseName);
            //condNode.addNodeToLeaves(ifNode);
            preIfNodes = ifNode;
            ifStatements.pop();
            return;
        }
        
        //函数调用
        if(line.matches("\\s*\\w*\\(.*\\);")){
        	System.out.println("函数调用："+line);
        	MethodCallNodeList.add(ctx);
        }
        //case default
        if(line.startsWith("case")||line.startsWith("default")) {
        	casedefaultFlag = true;
        	preCaseFlag = true;
        }else{
        	if(casedefaultFlag){
        		if(preCaseFlag){
        			//上一个为case则添加，否则只是修改
        			caseOrdefaultStatements.push(line);
        		}else{
        			String preStr = caseOrdefaultStatements.pop();
        			caseOrdefaultStatements.push(preStr+line);
        		}
            }
        	if(preCaseFlag){
        		preCaseFlag = false;
        	}
        }
        
        //其他块语句处理
        if(!ifStatements.contains(ctx) && !elseStatements.contains(ctx) && line.length() > 2 && line.charAt(0)=='{' && line.charAt(line.length()-1)=='}'){
        	
        	String otherCodes = otherSentences(line.substring(1, line.length()-1));
        	if(otherCodes.length()>2){
        		/*CLexer lexer = new CLexer(CharStreams.fromString("i=j;max=i;dd=22;i++;printf(\"%d\",i);"));
            	CommonTokenStream tokens = new CommonTokenStream(lexer);
            	CParser parser = new CParser(tokens);
            	ParseTree tree = parser.declaration();*/
        		//普通语句块包括赋值运算，自加自减，左右位移，函数调用，三元运算符
        		System.out.println("NormalNode:"+otherCodes);
            	NormalNode normalNode = new NormalNode(getId() + "其他块\n" + "{" + otherCodes + "}" + "\n" + def_use(otherCodes));
            	currentNode.addSuccessor(normalNode);
            	currentNode = normalNode;
        	}
        }
    }
    public static String lastSentence = "";
    @Override
    public void exitStatement(CParser.StatementContext ctx) {
    	System.out.println("exitStatement:"+ctx.getText());
    	if(!inMethod) return;  
    	if(elseStatements.contains(ctx)) {
            //GraphNode condNode = conditions.getFirst();
    		String elseCodes = otherSentences(ctx.getText().substring(1, ctx.getText().length()-1));
            ElseNode elseNode = new ElseNode(getId() + "else\n" + "{" +elseCodes + "}"+ "\n" + def_use(ctx.getText().substring(1, ctx.getText().length()-1)));
            //condNode.addNodeToLeaves(elseNode);
            preElseNodes = elseNode;
            elseStatements.pop();
            return;
        }
    	
    	//其他块语句处理
        String line = ctx.getText().toString();
        
        if(!ifStatements.contains(ctx) && !elseStatements.contains(ctx) && line.length() > 2 && line.charAt(0)=='{' && line.charAt(line.length()-1)=='}'){
        	String otherCodes = otherSentences2(line.substring(1, line.length()-1));
        	System.out.println("otherCodes="+otherCodes);
        	if(otherCodes.length()>2){
            	NormalNode normalNode = new NormalNode(getId() + "其他块\n" + "{" + otherCodes + "}" + "\n" + def_use(otherCodes));
            	currentNode.addSuccessor(normalNode);
            	currentNode = normalNode;
        	}
        }
        
        //函数结束前最后语句模块
        if(conditions.isEmpty() && cycleEndNodes.isEmpty() && !innerStruct(line)){
        	lastSentence = lastSentence + line;
        }
       
    }

    @Override
    public void enterJumpStatement(CParser.JumpStatementContext ctx) {
    	System.out.println("enterJumpStatement:"+ctx.getText());
        if(!inMethod) return;
        if(!lastSentence.isEmpty()){
        	
	        NormalNode normalNode = new NormalNode(getId() + "其他块\n" + "{" + lastSentence + "}" + "\n" + def_use(lastSentence));
	    	currentNode.addSuccessor(normalNode);
	    	currentNode = normalNode;
	        lastSentence = "";
        }
        
        String text = ctx.getText();
        
        if(text.startsWith("return")) {
            ReturnStmtNode returnStmtNode = new ReturnStmtNode(getId() + "Return");
            //currentNode.addSuccessor(returnStmtNode);
            unJumpNode = returnStmtNode;
            returnStmtNode.addSuccessor(exitNode);
        }
        else if(text.startsWith("break")) {
            BreakStmtNode breakStmtNode = new BreakStmtNode(getId() +"Break");
            breakStmtNode.addSuccessor(cycleEndNodes.getFirst());
            currentNode = conditions.getFirst();
            unJumpNode = breakStmtNode;
        }
        else if(text.startsWith("continue")) {
            ContinueStmtNode continueStmtNode = new ContinueStmtNode(getId() + "Continue");
            //currentNode.addSuccessor(continueStmtNode);
            unJumpNode = currentNode;
            continueStmtNode.addSuccessor(cycleBeginNodes.getFirst());
            GraphNode condNode = conditions.getFirst();
            currentNode = condNode;
        }
        

    }
    
    @Override
    public void enterIterationStatement(CParser.IterationStatementContext ctx) {
    	System.out.println("enterIterationStatement:"+ctx.getText());
        if(!inMethod) return;
        if(!lastSentence.isEmpty()){
	        NormalNode normalNode = new NormalNode(getId() + "其他块\n" + "{" + lastSentence + "}" + "\n" + def_use(lastSentence));
	    	currentNode.addSuccessor(normalNode);
	    	currentNode = normalNode;
	        lastSentence = "";
        }
        
        String text = ctx.getText();
        GraphNode beginNode = null;
        GraphNode endNode = null;
        ConditionNode condNode = new ConditionNode(getId() + "判断条件");
        
        //System.out.println("text="+text);
        if(text.startsWith("while")) {
            beginNode = new WhileBeginNode(getId() + "While开始");
            endNode = new WhileEndNode(getId() + "While结束");
            condNode.setParentType("while");
        }
        else if(text.startsWith("for")) {
            beginNode = new ForBeginNode(getId() + "For开始");
            endNode = new ForEndNode(getId() + "For结束");
            condNode.setParentType("for");
        }
        else if(text.startsWith("switch")) {
            beginNode = new ForBeginNode(getId() + "Switch开始");
            endNode = new ForEndNode(getId() + "Switch结束");
            condNode.setParentType("switch");
        }
        else if(text.startsWith("do")) {
            beginNode = new DoWhileBeginNode(getId() + "DoWhile开始");
            endNode = new DoWhileEndNode(getId() + "DoWhile结束");
            condNode.setParentType("dowhile");
            String line = text.substring(text.indexOf("while(")+6, text.lastIndexOf(")"));
            condNode.setName(condNode.getName() + "\n" + line + "\n" + use(line));
        }
        else {
            LOGGER.warn("Unknown iteration statement");
        }
        cycleBeginNodes.push(beginNode);
        conditions.push(condNode);
        //如果是选择语句则暂时无法确定前驱
        System.out.println("父节点类型："+currentNode.getParentType());
        if(!currentNode.getParentType().equals("if") && !currentNode.getParentType().equals("switch")) currentNode.addSuccessor(beginNode);
        else {
        	unPreNode = beginNode;
        }
        beginNode.addSuccessor(condNode);
        currentNode = condNode;

        cycleEndNodes.push(endNode);
    }

    @Override
    public void exitIterationStatement(CParser.IterationStatementContext ctx) {
    	System.out.println("exitIterationStatement:"+ctx.getText());
        if(!inMethod) return;
        GraphNode beginNode = cycleBeginNodes.pop();
        GraphNode endNode = cycleEndNodes.pop();
        
        beginNode.addNodeToLeaves(beginNode, endNode);

        ConditionNode condNode = (ConditionNode) conditions.pop();
        
        condNode.addSuccessor(endNode);
        currentNode = endNode;
    }
    
    public static boolean innerStruct(String str){
    	if(str.startsWith("if(") || str.startsWith("while(") || str.startsWith("switch(") || str.startsWith("return") || str.startsWith("continue")
    	    	|| str.startsWith("for(") || str.startsWith("do{")||str.startsWith("case")||str.startsWith("break")||str.startsWith("default:")) return true;
    	return false;
    }
    public static String innerStructIndex(String name){
    	if(name.contains("default:")){
    		name = name.substring(0, name.indexOf("default:"));
    	}
    	if(name.contains("case")){
    		name = name.substring(0, name.indexOf("case"));
    	}
    	if(name.contains("break;")){
    		name = name.substring(0, name.indexOf("break;"));
    	}
    	if(name.contains("return")){
    		name = name.substring(0, name.indexOf("return"));
    	}
    	if(name.contains("continue")){
    		name = name.substring(0, name.indexOf("continue"));
    	}
    	if(name.contains("if(")){
    		name = name.substring(0, name.indexOf("if("));
    	}
    	if(name.contains("for(")){
    		name = name.substring(0, name.indexOf("for("));
    	}
    	if(name.contains("while(")){
    		name = name.substring(0, name.indexOf("while("));
    	}
    	
    	return name;
    }
    //花括号内头部语句块
    public static String otherSentences(String str){
    	String name = "";
    	int end = 0;
    	for(int i=0;i<str.length();i++){
			String newStr = str.substring(i);
			if(innerStruct(newStr)) {
				//System.out.println("newStr="+newStr);
				end = i;
				break;
			}
			if(i==str.length()-1) end = str.length();
		}
    	name = str.substring(0, end);
    	return name;
    }
    //花括号内尾部语句块
    public static String otherSentences2(String str){
    	String name = "";
    	int start = str.length()-1;
    	for(int i=str.length()-1;i>=0;i--){
			char ch = str.charAt(i);
			if(ch=='}'){//遇到第一个}就停止
				start = i;
				break;
			}
			
		}
    	name = str.substring(start+1);
    	return innerStructIndex(name);
    }
    //define
    public static String def_use(ParseTree ctx,int type){
    	String def_use = "";
    	switch(type){
    		case 0://定义声明
    			ParseTree children = ctx.getChild(1);//该节点包含变量赋值部分
            	String childStr[] = children.getText().split(",");
            	String def  = "def("+childStr.length+"):{";
            	for (int i=0;i<childStr.length;i++) {
    				String name = childStr[i].split("=")[0];//变量声明只需要看等号左边
    				if(i==childStr.length-1) def = def + name;
    				else def = def + name + ",";
    			}
            	def = def + "}";
            	def_use = def;
            	break;
    		case 1://普通赋值
    			
    			break;
    		case 2://函数传参
    			
    			break;
    	}
    	return def_use;
    }
    
    public static String def_use(LinkedList<ParseTree> ctxList,int type){
    	String def_use = "";
    	switch(type){
    		case 0://定义声明
    			int count = 0;
    			String def = "";
    			for (int j=0;j<ctxList.size();j++) {
    				ParseTree children = ctxList.get(j).getChild(1);//该节点包含变量赋值部分
                	String childStr[] = children.getText().split(",");
                	for (int i=0;i<childStr.length;i++) {
                		count++;
        				String name = childStr[i].split("=")[0];//变量声明只需要看等号左边
        				if(j==ctxList.size()-1 && i==childStr.length-1) def = def + name;
        				else def = def + name + ",";
        			}
				}
    			
            	def  = "def("+count+"):{" +def;
            	
            	def = def + "}";
            	def_use = def;
            	break;
    		case 1://普通赋值
    			
    			break;
    		case 2://函数传参
    			
    			break;
    	}
    	return def_use;
    }
    
    public static String def_use(String text){
    	text = innerStructIndex(text);
    	String str[] = text.split(";");
    	ArrayList<String> defNameList = new ArrayList<>();
		ArrayList<String> useNameList = new ArrayList<>();
    	for (int i=0;i<str.length;i++) {
    		String defName = "";
    		if(!innerStruct(str[i])){
    		if(str[i].contains("=")||str[i].contains("++")||str[i].contains("--")||str[i].contains("scanf")){//存在def操作
    			String nowStr = str[i].replaceAll(" ", "");
    			if(nowStr.contains("+=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("+="));
    				String useName = nowStr.substring(nowStr.indexOf("+=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("-=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("-="));
    				String useName = nowStr.substring(nowStr.indexOf("-=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("*=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("*="));
    				String useName = nowStr.substring(nowStr.indexOf("*=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("/=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("/="));
    				String useName = nowStr.substring(nowStr.indexOf("/=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("%=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("%="));
    				String useName = nowStr.substring(nowStr.indexOf("%=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("&=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("&="));
    				String useName = nowStr.substring(nowStr.indexOf("&=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("^=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("^="));
    				String useName = nowStr.substring(nowStr.indexOf("^=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("|=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("|="));
    				String useName = nowStr.substring(nowStr.indexOf("|=")+2,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("<<=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("<<="));
    				String useName = nowStr.substring(nowStr.indexOf("<<=")+3,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains(">>=")) {
    				defName = nowStr.substring(0,nowStr.indexOf(">>="));
    				String useName = nowStr.substring(nowStr.indexOf(">>=")+3,nowStr.length());
    				useNameList = useList(useNameList,useName);
    			}else
    			if(nowStr.contains("=")) {
    				defName = nowStr.substring(0,nowStr.indexOf("="));
    				String useName = nowStr.substring(nowStr.indexOf("=")+1,nowStr.length());
    				useNameList = useList(useNameList,useName);
        		}else{
        			if(nowStr.contains("++")){
        				defName = nowStr.substring(0,nowStr.indexOf("++"));
        				useNameList = useList(useNameList,defName);
        			}
        			if(nowStr.contains("--")){
        				defName = nowStr.substring(0,nowStr.indexOf("--"));
        				useNameList = useList(useNameList,defName);
        			}
        			if(nowStr.contains("scanf")){
        				String defNames = nowStr.substring(nowStr.indexOf(",")+1, nowStr.indexOf(")")).replaceAll("&", "");
        				for (String string : defNames.split(",")) {
        					defNameList.add(string);
						}
        				
        			}
        			
        		}
    			
    			//defName不在列表中则添加该defName
    			if(!defName.isEmpty() && !defNameList.contains(defName)) defNameList.add(defName);
    			
    		}else{//考虑三元运算符以及函数调用
    			if(str[i].matches(".*\\?.*\\:.*")){
    				//三元运算符的正则表达式
    			}
    			if(str[i].matches("\\s*\\w*\\(.*\\)")){
    				//函数调用
    				//String functionName = str[i].substring(0,str[i].indexOf("("));
    				String useName = str[i].substring(str[i].indexOf("(")+1,str[i].lastIndexOf(")"));
    				if(useName.contains("&")){
    					String defNames = useName.replaceAll("&", "");
        				for (String string : defNames.split(",")) {
        					defNameList.add(string);
						}
    				}else {
    					useNameList = useList(useNameList,useName);
    				}
    			}else{
    				if(text.contains("==")||text.contains("!=")||text.contains(">")||text.contains("<")||text.contains(">=")||text.contains("<=")){
    					String str1 = str[i].replaceAll(" ", "");
    					if(str1.contains("==")){
    						String useName1 = str1.substring(0, str1.indexOf("=="));
    						if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName1);
    						String useName2 = str1.substring(str1.indexOf("==")+2,str1.length());
    						if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName2);
    					}else
    					if(str1.contains("!=")){
    						String useName1 = str1.substring(0, str1.indexOf("!="));
    						if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName1);
    						String useName2 = str1.substring(str1.indexOf("!=")+2,str1.length());
    						if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName2);
    					}else
    					if(str1.contains(">")){
    						String useName1 = str1.substring(0, str1.indexOf(">"));
    						if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName1);
    						String useName2 = str1.substring(str1.indexOf(">")+1,str1.length());
    						if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName2);
    					}else
    					if(str1.contains(">=")){
    						String useName1 = str1.substring(0, str1.indexOf(">="));
    						if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName1);
    						String useName2 = str1.substring(str1.indexOf(">=")+2,str1.length());
    						if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName2);
    					}else
    					if(str1.contains("<")){
    						String useName1 = str1.substring(0, str1.indexOf("<"));
    						if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName1);
    						String useName2 = str1.substring(str1.indexOf("<")+1,str1.length());
    						if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName2);
    					}else
    					if(str1.contains("<=")){
    						String useName1 = str1.substring(0, str1.indexOf("<="));
    						if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName1);
    						String useName2 = str1.substring(str1.indexOf("<=")+2,str1.length());
    						if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
    						useNameList = useList(useNameList,useName2);
    					}
    					
    				}
    			}
    		}
    		System.out.println("def_use:"+str[i]);
    		}
		}//for end
    	String defName = "def("+defNameList.size()+"):{";
    	for (int i=0;i<defNameList.size();i++) {
			if(i==defNameList.size()-1) defName = defName + defNameList.get(i);
			else defName = defName + defNameList.get(i) + ",";
		}
    	defName = defName + "}";
    	String useName = "use("+useNameList.size()+"):{";
    	for (int i=0;i<useNameList.size();i++) {
			if(i==useNameList.size()-1) useName = useName + useNameList.get(i);
			else useName = useName + useNameList.get(i) + ",";
		}
    	useName = useName + "}";
    	return defName + "\n" +useName;
    }
    public static String use(String text){
		ArrayList<String> useNameList = new ArrayList<>();
		if(!innerStruct(text)){
		if(text.contains("==")||text.contains("!=")||text.contains(">")||text.contains("<")||text.contains(">=")||text.contains("<=")){
			String str = text.replaceAll(" ", "");
			if(str.contains("==")){
				String useName1 = str.substring(0, str.indexOf("=="));
				if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
				useNameList = useList(useNameList,useName1);
				String useName2 = str.substring(str.indexOf("==")+2,str.length());
				if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
				useNameList = useList(useNameList,useName2);
			}else
			if(str.contains("!=")){
				String useName1 = str.substring(0, str.indexOf("!="));
				if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
				useNameList = useList(useNameList,useName1);
				String useName2 = str.substring(str.indexOf("!=")+2,str.length());
				if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
				useNameList = useList(useNameList,useName2);
			}else
			if(str.contains(">")){
				String useName1 = str.substring(0, str.indexOf(">"));
				if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
				useNameList = useList(useNameList,useName1);
				String useName2 = str.substring(str.indexOf(">")+1,str.length());
				if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
				useNameList = useList(useNameList,useName2);
			}else
			if(str.contains(">=")){
				String useName1 = str.substring(0, str.indexOf(">="));
				if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
				useNameList = useList(useNameList,useName1);
				String useName2 = str.substring(str.indexOf(">=")+2,str.length());
				if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
				useNameList = useList(useNameList,useName2);
			}else
			if(str.contains("<")){
				String useName1 = str.substring(0, str.indexOf("<"));
				if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
				useNameList = useList(useNameList,useName1);
				String useName2 = str.substring(str.indexOf("<")+1,str.length());
				if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
				useNameList = useList(useNameList,useName2);
			}else
			if(str.contains("<=")){
				String useName1 = str.substring(0, str.indexOf("<="));
				if(useName1.matches("\\s*\\w*\\(.*\\)")) useName1 = useName1.substring(useName1.indexOf("(")+1,useName1.lastIndexOf(")"));
				useNameList = useList(useNameList,useName1);
				String useName2 = str.substring(str.indexOf("<=")+2,str.length());
				if(useName2.matches("\\s*\\w*\\(.*\\)")) useName2 = useName2.substring(useName2.indexOf("(")+1,useName2.lastIndexOf(")"));
				useNameList = useList(useNameList,useName2);
			}
			
		}else{
			useNameList = useList(useNameList,text);
		}
		}
    	String useName = "use("+useNameList.size()+"):{";
    	for (int i=0;i<useNameList.size();i++) {
			if(i==useNameList.size()-1) useName = useName + useNameList.get(i);
			else useName = useName + useNameList.get(i) + ",";
		}
    	useName = useName + "}";
    	return useName;
    }
    public static ArrayList<String> useList(ArrayList<String> useNameList,String useName){
    	useName = useName.replaceAll("\\(", "_").replaceAll("\\)", "_").replaceAll("%", "_")
				.replaceAll("\\+", "_").replaceAll("\\-", "_").replaceAll("\\*", "_")
				.replaceAll("\\/", "_").replaceAll("\\>>", "_").replaceAll("\\<<", "_")
				.replaceAll("\\&", "_").replaceAll("\\^", "_").replaceAll("\\|", "_")
				.replaceAll(",", "_").replaceAll("\\.", "_").replaceAll("\\>", "_")
				.replaceAll("\\<", "_").replaceAll("!=", "_").replaceAll("long", "_")
				.replaceAll("int", "_").replaceAll("double", "_").replaceAll("float", "_")
				.replaceAll("short", "_").replaceAll("char", "_").replaceAll("const", "_")
				.replaceAll("break;", "_");
    	String newUseName = "";
    	boolean flag = true;
    	for(int i=0;i<useName.length();i++){
    		char ch = useName.charAt(i);
    		if(ch=='"'){
    			if(flag) flag = false;//表示开始进入双引号字符串内
    			else flag = true;//双引号之外
    		}else
    		if(flag) newUseName += ch;
    	}
		String s[]=newUseName.split("_");
		for(int j=0;j<s.length;j++){
    		if(!s[j].matches("\\d*") && !s[j].isEmpty() && !useNameList.contains(s[j])){
    			useNameList.add(s[j]);
    			if(s[j].contains("[")){
    				String indexStr = findindexStr(s[j]);
    				if(!indexStr.matches("\\d*")) useNameList.add(indexStr);
    			}
    			//System.out.println(s[j]);
    		}
    	}
		return useNameList;
    }
    public static String findindexStr(String text){
    	if(text.contains("[")){
    		text = text.substring(text.indexOf("[")+1, text.indexOf("]"));
        	return findindexStr(text);
    	}
    	return text;
    	
    }
}
